﻿using Inaction.UI.ComponentModel.Design;
using Inaction.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace Inaction.UI.Settings
{
    public class TableClassTypeHelper
    {
        static TableClassTypeHelper instance;

        BarManager barManager;

        string outputPath;

        private TableClassTypeHelper() { }
        public static void Init(string outputPath)
        {
            if (instance == null)
            {
                instance = new TableClassTypeHelper();
            }
            instance.barManager = BarManagerDesigner.WorkingBarManager;
            instance.outputPath = outputPath;
        }
        public static BindingSource GetClassBindingSource(string tableName)
        {
            var type = instance.GetTypeFromTableName(tableName);
            if (type == null)
            {
                return null;
            }
            if (instance == null) return null;
            var bindingInfo = instance.barManager.BindingInfos.FirstOrDefault(p => p.ListType == type);
            if (bindingInfo != null)
            {
                return bindingInfo.BindingSource;
            }
            var bindingSource = ComponentCache.GetBindingSource(type);
            if (bindingSource == null)
            {
                bindingSource = new BindingSource(instance.barManager.Container);
                bindingSource.DataSource = type;
                var siteName = type.Name[0].ToString().ToLower() + type.Name.Substring(1) + "BindingSource";
                if (instance.barManager.Site.Container.Components[siteName] == null)
                {
                    bindingSource.Site.Name = siteName;
                }
                instance.barManager.Container.Add(bindingSource);
                ComponentCache.Components.Add(bindingSource);
            }
            if (!instance.barManager.BindingInfos.Any(p => p.BindingSource == bindingSource))
            {
                var bi = new BindingInfo(instance.barManager.Container)
                    {
                        BindingSource = bindingSource,
                        QueryOnLoad = true,
                        AllowEdit = false,
                        AllowNew = false,
                        AllowRemove = false
                    };
                instance.barManager.BindingInfos.Add(bi);
            }
            return bindingSource;
        }

        private Type GetTypeFromTableName(string tableName)
        {
            var files = System.IO.Directory.GetFiles(outputPath, "*.Business.*.dll");
            foreach (var file in files)
            {
                var bytes = System.IO.File.ReadAllBytes(file);
                var assembly = Assembly.Load(bytes);
                foreach (var type in assembly.GetTypes())
                {
                    if (type.IsGenericType || type.IsAbstract || type.GetInterface(typeof(IEntityList).FullName) == null) continue;
                    var genericType = type.BaseType;
                    while (!genericType.IsGenericType)
                    {
                        genericType = genericType.BaseType;
                    }
                    try
                    {
                        var gt = genericType.GetGenericArguments()[1];
                        var classInfo = Inaction.Mapping.ClassInfo.LoadInfo(gt);
                        if (classInfo.TableName == tableName)
                        {
                            return type;
                        }
                    }
                    catch { continue; }
                }
            }
            return null;
        }
    }
}
